package com.xayy.health.mgt.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.kawins.base.result.ResultBody;
import cn.kawins.mybatis.base.BaseController;
import com.github.pagehelper.PageInfo;
import com.xayy.health.core.enums.BackupTypeEnum;
import com.xayy.health.core.enums.RelationTypeEnum;
import com.xayy.health.mgt.model.*;
import com.xayy.health.mgt.model.dto.NodeDto;
import com.xayy.health.mgt.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangxa
 */
@RestController
@RequestMapping(value = "/satellite1")
@Api(tags = "卫星管理")
public class SatelliteController extends BaseController<Satellite> {

    @Autowired
    private SatelliteService satelliteService;
    @Autowired
    private SatelliteNodeService satelliteNodeService;
    @Autowired
    private SatelliteEdgeService satelliteEdgeService;
    @Autowired
    private SatelliteParamService satelliteParamService;
    @Autowired
    private SatelliteRelationService satelliteRelationService;


    /**
     * 查询节点树
     *
     * @return ResultBody
     */
    @ApiOperation(value = "树结构(不带卫星)")
    @GetMapping("getTree")
    public ResultBody getTree() {
        return ResultBody.success(satelliteService.selectTree());
    }

    /**
     * 获取左侧树
     * @return ResultBody
     */
    @ApiOperation(value = "树结构(带卫星)")
    @GetMapping("getLeftTree")
    public ResultBody getLeftTree() {
        return ResultBody.success(satelliteService.selectLeftTree());
    }

    /**
     * 获取节点树左侧信第三方接口
     * @param pageNum  页码
     * @param pageSize 页数
     * @param xingType 卫星类型
     * @return 结果日志
     */
    @ApiOperation(value = "树结构(第三方接口)")
    @GetMapping("getLeftTreeByOther")
    public ResultBody getLeftTreeByOther(@RequestParam Integer pageNum, @RequestParam Integer pageSize,
                                         @RequestParam String xingType) {
        return satelliteService.getLeftTreeByOther(pageNum, pageSize, xingType).body();
    }

    /**
     * 图谱(第三方接口)
     * @return ResultBody
     */
    @ApiOperation(value = "图谱(第三方接口)")
    @GetMapping("selectAtlas")
    public ResultBody selectAtlas() {
        Map<String, List<Map<String, Object>>> map = new HashMap<>(2);

        List<Map<String, Object>> list1 = new ArrayList<>();
        Map<String, Object> map1 = new HashMap<>(2);
        map1.put("id", "11034");
        map1.put("label", "星");
        list1.add(map1);
        Map<String, Object> map11 = new HashMap<>(2);
        map11.put("id", "11059");
        map11.put("label", "分系统");
        list1.add(map11);
        Map<String, Object> map12 = new HashMap<>(2);
        map12.put("id", "11057");
        map12.put("label", "分系统");
        list1.add(map12);

        List<Map<String, Object>> list2 = new ArrayList<>();
        Map<String, Object> map2 = new HashMap<>(4);
        map2.put("id", "4540");
        map2.put("label", "星_分系统");
        map2.put("start", "11034");
        map2.put("end", "11057");
        list2.add(map2);
        Map<String, Object> map3 = new HashMap<>(4);
        map3.put("id", "4541");
        map3.put("label", "星_分系统");
        map3.put("start", "11034");
        map3.put("end", "11059");
        list2.add(map3);

        map.put("nodes", list1);
        map.put("relationships", list2);

        return ResultBody.success(map);
    }

    /**
     * 新增卫星
     * @param satellite 卫星对象
     * @return ResultBody
     */
    @ApiOperation(value = "新增卫星")
    @PostMapping("addTree")
    public ResultBody addTree(@RequestBody Satellite satellite) {
        return ResultBody.success(satelliteService.insert(satellite));
    }

    /**
     * 新增卫星
     * @param satellite 编辑卫星
     * @return ResultBody
     */
    @ApiOperation(value = "编辑卫星")
    @PostMapping("editTree")
    public ResultBody editTree(@RequestBody Satellite satellite) {
        return ResultBody.success(satelliteService.updateByIdSelective(satellite));
    }

    /**
     * 删除卫星
     * @param id 卫星id
     * @return ResultBody
     */
    @ApiOperation(value = "删除卫星")
    @GetMapping("deleteTree/{id}")
    public ResultBody deleteTree(@PathVariable Long id) {
        Long pid = satelliteService.selectById(id).getPid();
        if (pid == 0) {
            return ResultBody.failed("根节点不能删除!");
        }
        if (satelliteService.hasChild(id)) {
            return ResultBody.failed("存在子节点,无法删除!");
        }
        satelliteService.deleteById(id);
        return ResultBody.success();
    }

    /**
     * 健康评估根据卫星id获取树结构
     * @param id 卫星id
     * @return ResultBody
     */
    @GetMapping("/getDefRootId/{id}")
    @ApiOperation(value = "健康评估根据卫星id获取树结构")
    public ResultBody getDefRootId(@ApiParam("卫星id") @PathVariable Long id) {
        return ResultBody.success(satelliteNodeService.getDefRootId(id));
    }

    /**
     * 健康评估获取树结构(外部接口)
     * @param node 卫星节点信息
     * @return ResultBody
     */
    @PostMapping("getDefRoot")
    @ApiOperation(value = "健康评估获取树结构(外部接口)")
    public ResultBody getDefRoot(@RequestBody SatelliteNode node) {
        return ResultBody.success(satelliteNodeService.getDefRoot(node));
    }

    /**
     * 获取卫星拓扑图节点(拓扑图)
     * @param id 节点id
     * @return 拓扑节点信息
     */
    @ApiOperation(value = "获取卫星拓扑图节点(拓扑图)")
    @GetMapping("getNodes/{id}")
    public ResultBody getNodes(@PathVariable Long id) {
        Map<String, Object> map = satelliteNodeService.getList(id);
        return ResultBody.success(map);
    }

    /**
     * 获取卫星拓扑图节点(单节点信息)
     * @param id 节点id
     * @return ResultBody
     */
    @ApiOperation(value = "获取卫星拓扑图节点(单节点信息)")
    @GetMapping("getNodeInfo/{id}")
    public ResultBody getNodeInfo(@PathVariable Long id) {
        SatelliteNode satelliteNode = satelliteNodeService.selectById(id);
        return ResultBody.success(satelliteNode);
    }

    /**
     * 获取卫星拓扑图节点(分页)
     * @param nodeDto 节点信息
     * @return ResultBody
     */
    @ApiOperation(value = "获取卫星拓扑图节点(分页)")
    @PostMapping("pageNode")
    public ResultBody pageNode(@RequestBody NodeDto nodeDto) {
        PageInfo<SatelliteNode> pageList = satelliteNodeService.pageList(nodeDto);
        return ResultBody.success(pageList);
    }

    /**
     * 新增拓扑图节点
     * @param satelliteNode 拓扑图节点入参
     * @return ResultBody
     */
    @ApiOperation(value = "新增拓扑图节点")
    @PostMapping("addNode")
    public ResultBody addNode(@RequestBody SatelliteNode satelliteNode) {
        satelliteNode.setCreateTime(DateUtil.date());
        satelliteNodeService.save(satelliteNode);
        return ResultBody.success();
    }

    /**
     * 修改拓扑图节点
     * @param satelliteNode 拓扑图节点入参
     * @return ResultBody
     */
    @ApiOperation(value = "修改拓扑图节点")
    @PostMapping("updateNode")
    public ResultBody updateNode(@RequestBody SatelliteNode satelliteNode) {
        satelliteNodeService.updateByIdSelective(satelliteNode);
        return ResultBody.success();
    }

    /**
     * 删除拓扑图节点
     * @param id 拓扑图节点id
     * @return ResultBody
     */
    @ApiOperation(value = "删除拓扑图节点")
    @GetMapping("deleteNode/{id}")
    public ResultBody deleteNode(@PathVariable Long id) {
        SatelliteNode satelliteNode = satelliteNodeService.selectById(id);
        if (Objects.equals(satelliteNode.getPid(), satelliteNode.getId())) {
            return ResultBody.failed("根节点不能删除!");
        }
        if (satelliteNodeService.hasEdge(id)) {
            return ResultBody.failed("存在子节点,无法删除!");
        }
        satelliteNodeService.deleteById(id);
        SatelliteEdge satelliteEdge = new SatelliteEdge();
        satelliteEdge.setTo(id);
        satelliteEdgeService.delete(satelliteEdge);
        return ResultBody.success();
    }

    /**
     * 新增参数
     * @param satelliteParam 入参
     * @return ResultBody
     */
    @ApiOperation(value = "新增参数")
    @PostMapping("addParam")
    public ResultBody addParam(@RequestBody SatelliteParam satelliteParam) {
        SatelliteParam satelliteParamQuery = new SatelliteParam();
        satelliteParamQuery.setParamName(satelliteParam.getParamName());
        List<SatelliteParam> satelliteParams = satelliteParamService.select(satelliteParamQuery);
        if (!satelliteParams.isEmpty()) {
            return ResultBody.failed("参数名称已存在!");
        }
        satelliteParamService.saveAndUpdate(satelliteParam);
        return ResultBody.success();
    }

    /**
     * 删除参数
     * @param name 参数名称
     * @return ResultBody
     */
    @ApiOperation(value = "删除参数")
    @GetMapping("deleteParam/{name}")
    public ResultBody deleteParam(@PathVariable String name) {
        SatelliteParam satelliteParam = new SatelliteParam();
        satelliteParam.setParamName(name);
        satelliteParamService.delete(satelliteParam);
        return ResultBody.success();
    }

    /**
     * 获取参数列表
     * @param nodeId 节点id
     * @return ResultBody
     */
    @ApiOperation(value = "获取参数列表")
    @GetMapping("getParams/{nodeId}")
    public ResultBody getParams(@PathVariable Long nodeId) {
        SatelliteParam satelliteParam = new SatelliteParam();
        satelliteParam.setNodeId(nodeId);
        List<SatelliteParam> satelliteParamList = satelliteParamService.select(satelliteParam);
        satelliteParamList.forEach(e -> e.setName(e.getParamName()));
        return ResultBody.success(satelliteParamList);
    }

    /**
     * 筛选遥测参数
     * @param satelliteId 卫星id
     * @param keyword 关键字
     * @return ResultBody
     */
    @ApiOperation(value = "筛选遥测参数")
    @GetMapping("screenParam/{satelliteId}")
    public ResultBody screenParam(@PathVariable Long satelliteId, @RequestParam(required = false) String keyword, @RequestParam(required = false) String searchKey) {
        List<SatelliteParam> satelliteParams = satelliteParamService.selectByOther(satelliteId);
        if (StrUtil.isNotBlank(keyword)) {
            satelliteParams = satelliteParams.stream()
                    .filter(x -> StrUtil.isNotBlank(x.getParamName()) && StrUtil.isNotBlank(x.getTelemetryCode()))
                    .filter(x -> x.getParamName().toLowerCase().contains(keyword.toLowerCase()) || x.getTelemetryCode().toLowerCase().contains(keyword.toLowerCase()))
                    .collect(Collectors.toList());
        }

        if(StrUtil.isNotBlank(searchKey)){
            satelliteParams=satelliteParams.stream().filter(x ->x.getParamName().contains(searchKey)).collect(Collectors.toList());
        }
        return ResultBody.success(satelliteParams);
    }


    /**
     * 新增关系
     * @param satelliteRelation 入参
     * @return ResultBody
     */
    @ApiOperation(value = "新增关系")
    @PostMapping("addRelation")
    public ResultBody addRelation(@RequestBody SatelliteRelation satelliteRelation) {
        satelliteRelationService.saveAndUpdate(satelliteRelation);
        return ResultBody.success();
    }

    /**
     * 获取关系信息
     * @param nodeId 节点id
     * @return ResultBody
     */
    @ApiOperation(value = "获取关系信息")
    @GetMapping("getRelationInfo/{nodeId}")
    public ResultBody getRelationInfo(@PathVariable Long nodeId) {
        SatelliteRelation satelliteRelationQuery = new SatelliteRelation();
        satelliteRelationQuery.setNodeId(nodeId);
        SatelliteRelation satelliteRelation = satelliteRelationService.selectOne(satelliteRelationQuery);
        if (BeanUtil.isEmpty(satelliteRelation)) {
            return ResultBody.success(new SatelliteRelation());
        } else {
            satelliteRelation.setRelationTypeName(RelationTypeEnum.valueof(satelliteRelation.getRelationType()));
            satelliteRelation.setBackupTypeName(BackupTypeEnum.valueof(satelliteRelation.getBackupType()));
            return ResultBody.success(satelliteRelation);
        }
    }

    /**
     * 获取设备参数列表(不再过滤，查询全量的)
     * @param satId 卫星id
     * @param nodeId 设备id
     * @return ResultBody
     */
    @ApiOperation(value = "获取设备参数列表")
    @GetMapping("getProperties/{satId}/{nodeId}")
    public ResultBody getProperties(@PathVariable(value = "satId") @ApiParam("卫星id") Long satId,
                                    @PathVariable(value = "nodeId") @ApiParam("设备id") Long nodeId) {
        return satelliteService.getProperties(satId, nodeId).body();
    }

    @ApiOperation(value = "获取健康评估列表")
    @PostMapping("healthRuleTable")
    public ResultBody getHealthRuleTable(@RequestBody SatelliteNode node) {
        return ResultBody.success(satelliteNodeService.getHealthRuleTable(node));
    }

}
